﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ITAP.ShprossesBuilder.Modelling.Components;
using System.Drawing;
using ITAP.ShprossesBuilder.Modelling;
using System.Drawing.Imaging;
using System.IO;
using ITAP.ShprossesBuilder.Utils;
using ITAP.ShprossesBuilder.Calculations;
using ITAP.ShprossesBuilder.Render;
using ITAP.ShprossesBuilder.Editor;
using ITAP.Core.Modelling;
using ITAP.Core.Utils;
using ITAP.Core.Calculations;

namespace ITAP.ShprossesBuilder.Operations {
    public class OperationGetModelsWmfBytes : IOperation
    {
        private int modelId;
        public OperationGetModelsWmfBytes(int modelId) {
            this.modelId = modelId;
        }

        private byte[] zippedBytes;

        public byte[] ZippedBytes {
            get {
                return zippedBytes;
            }
        }

        #region IOperation Members

        public string Name {
            get {
                return "Получить массив байтов Wmf модели";
            }
        }

        public OperationGroup OperationGroup {
            get {
                return OperationGroup.Other;
            }
        }

        public System.Drawing.Image Thumbnail {
            get {
                return null;
            }
        }

        public void Execute(ModelControl modelControl) {
            ModelCoordinateConverter coordinateConverter = new ModelCoordinateConverter();
            DraftRender render = new DraftRender();
            foreach(IComponent innerComponent in modelControl.ModelContainer.InnerComponents) {
                ModelCell modelCell = innerComponent as ModelCell;
                Model model = modelCell.Model;
                if(model.SerialNumber == modelId) {
                    RectangleF modelRect = modelCell.Model.BoundingBox;
                    ModelPoint center = new ModelPoint(modelRect.X + modelRect.Width / 2, modelRect.Y + modelRect.Height / 2);
                    RectangleF screenRect = coordinateConverter.ModelRectangleToScreenRectangle(modelRect, (int)modelRect.Width, (int)modelRect.Height, modelRect, center);
                    Bitmap bitmap = new Bitmap((int)screenRect.Width, (int)screenRect.Height);
                    Graphics ig = Graphics.FromImage(bitmap);

                    render.Initialize(ig, (int)modelRect.Width, (int)modelRect.Height, modelRect, coordinateConverter, center);
                    render.SetSizesFont(GlobalPreferences.Preferences.DraftDimensions.Font);

                    modelRect = render.GetModelBoundingBoxAfterDrawing(modelCell, (int)screenRect.Width, (int)screenRect.Height);
                    center = new ModelPoint(modelRect.X + modelRect.Width / 2, modelRect.Y + modelRect.Height / 2);
                    screenRect = coordinateConverter.ModelRectangleToScreenRectangle(modelRect, (int)modelRect.Width, (int)modelRect.Height, modelRect, center);
                    render.Initialize(ig, (int)modelRect.Width, (int)modelRect.Height, modelRect, coordinateConverter, center);
                    render.SetSizesFont(GlobalPreferences.Preferences.DraftDimensions.Font);
                    render.Visit(modelCell);
                    IntPtr hdc = ig.GetHdc();
                    Metafile metafile = new Metafile(hdc, screenRect, MetafileFrameUnit.Pixel, EmfType.EmfPlusDual);
                    ig.ReleaseHdc();
                    Graphics mg = Graphics.FromImage(metafile);
                    mg.PageUnit = GraphicsUnit.Pixel;
                    mg.Clear(Color.White);
                    render.Initialize(mg, (int)modelRect.Width, (int)modelRect.Height, modelRect, coordinateConverter, center);
                    render.SetSizesFont(GlobalPreferences.Preferences.DraftDimensions.Font);
                    render.Visit(modelControl.ModelContainer);
                    MemoryStream stream = new MemoryStream();

                    metafile.Save(stream, ImageFormat.Wmf);
                    MemoryStream zippedStream = new MemoryStream();
                    Archiver.Zip(stream, zippedStream);
                    zippedBytes = new byte[zippedStream.Length];
                    zippedStream.Seek(0, SeekOrigin.Begin);
                    zippedStream.Read(zippedBytes, 0, zippedBytes.Length);
                    zippedStream.Close();
                    stream.Close();

                    mg.Dispose();
                    ig.Dispose();

                    return;
                }

            }
        }

        public bool CanUndo {
            get {
                return false;
            }
        }

        #endregion
    }
}
